import React from 'react'
import { View, Text, OpenData, ScrollView, Image, Input, Switch } from '@tarojs/components'
import { AtTabBar, AtDrawer, AtButton, AtActivityIndicator, AtFloatLayout } from 'taro-ui'
import Taro from '@tarojs/taro'
import './index.scss'
import { IMAGES } from '../../uilts/images'
import { GetT } from '../../uilts/textLib'
import { appVersion, miniprogramDeveloper, hardwareDeveloper } from '../../uilts/config'
import { DeviceGroup } from '../../serverless/deviceGroup'
import { DeviceList } from '../../serverless/deviceList'
import { DeviceMode, DeviceModeHandlePath } from '../../serverless/deviceMode'
import { WeMqttApi } from '../../serverless/weMqttApi'

enum STATUS {
  LOADING,
}

enum PAGES {
  HOME = 0,
  ALERT = 1
}
// let iconv = require('iconv-lite');
let T = GetT()
export default class Index extends React.Component {

  state = {
    status: STATUS.LOADING,
    pageCurrent: PAGES.HOME,
    deviceGroupList: [] as DeviceGroup[],
    selectDeviceGroupIndex: 0,
    homeAtDrawerShow: false,
    addGroupInputShow: false,
    groupName: '',
    addGroupLoading: false,
    GetDeviceListNow: true,
    deviceList: [] as DeviceList[],
    deviceMode: [] as DeviceMode[],
    deviceInfoAtFloatLayoutIsOpened: false,
    selectDeviceIndex: 0,
    inputName: ''
  }

  async componentWillMount() {
    await this.getDeviceMode()
    await this.getDeviceGroup()
  }

  componentDidMount() { }

  componentWillUnmount() { }

  componentDidShow() { }

  componentDidHide() { }

  private createDeviceGroupLock = false;
  async getDeviceGroup() {
    try {
      const a = await DeviceGroup.GetDeviceGroup();
      if (a.length === 0 && !this.createDeviceGroupLock) {
        this.createDeviceGroupLock = true;
        // 创建默认分组，不允许删除
        await DeviceGroup.CreateDeviceGroup('默认分组', '我的默认分组', false)
        this.getDeviceGroup()
      } else {
        this.setState({
          deviceGroupList: a
        })
      }
    } catch (error) {
      console.error(error);
    }
    this.getDeviceList()
  }

  async getDeviceList() {
    try {
      const { deviceGroupList, selectDeviceGroupIndex } = this.state
      if (deviceGroupList.length > 0) {
        if (this._onGetDescribeDeviceTimeout) {
          clearTimeout(this._onGetDescribeDeviceTimeout)
        }
        this.setState({ GetDeviceListNow: true })
        const a = await DeviceList.GetDeviceList(deviceGroupList[selectDeviceGroupIndex].get_id());
        this.setState({
          deviceList: a,
          GetDeviceListNow: false
        })
        // 设置3秒后获取设备信息详情，避免因为用户频繁切换导致浪费网络资源
        this._onGetDescribeDeviceTimeout = setTimeout(() => {
          this.getDescribeDevice()
        }, 3000);
      }
    } catch (error) {
      console.error(error);
    }
  }

  async getDeviceMode() {
    try {
      const a = await DeviceMode.GetDeviceMode();
      console.log('deviceMode', a);
      this.setState({
        deviceMode: a,
      })
    } catch (error) {
      console.error(error);
    }
  }

  private _onGetDescribeDeviceTimeout: NodeJS.Timeout;
  async getDescribeDevice() {
    const { deviceList } = this.state
    if (deviceList.length > 0) {
      for (let index = 0; index < deviceList.length; index++) {
        const element = deviceList[index];
        const w = new WeMqttApi(element.info.deviceId)
        const a = await w.describeDevice()
        const b = await w.describeDeviceShadow()
        const msg = b.data.parseData.payload.state.reported.message
        const str = await w.gbkBase64toUtf8(msg)
        // console.log('utf8 str:', str)
        element.carouselText = str.data;
        element.describeDeviceInfo = a.data;
      }
    }
    this.setState({
      deviceList: deviceList
    })
  }

  handleClick(key: string, value: any) {
    this.setState({
      [key]: value
    })
  }

  onBindDeviceSelect() {
    const { deviceGroupList, selectDeviceGroupIndex } = this.state
    Taro.navigateTo({
      url: `/pages/bind_device_select/index?groupId=${deviceGroupList[selectDeviceGroupIndex].get_id()}`,
    })
  }

  addView() {
    const { GetDeviceListNow } = this.state
    return <View className='at-col at-col-12 list-periphery'>
      {/* 展示加载动画 */}
      {GetDeviceListNow === true && <View>
        <View className='loading center-horizontally'>
          <AtActivityIndicator content='拼了命的加载中...'></AtActivityIndicator>
        </View>
      </View>}
      {/* 展示空动画 */}
      {GetDeviceListNow === false && <View className='border' hoverClass='hover' hoverStartTime={20} hoverStayTime={70} onClick={() => {
        const { GetDeviceListNow } = this.state
        if (!GetDeviceListNow) {
          this.onBindDeviceSelect()
        }
      }}>
        <View>
          <View className='center-horizontally'>
            <Image className='image-empty' src={IMAGES.empty} />
          </View>
          <View className='center-horizontally'>
            <View className='text-empty'>空空如也，点击添加</View>
          </View>
        </View>
      </View>}
    </View>
  }

  alertInfo(title: string, msg: string, className: string = '') {
    return <View className='at-row alert-info'>
      <View className={`at-col at-col-4 view-white-space title ${className}`}><Text>{title}</Text></View>
      <View className={`at-col at-col-7 view-white-space msg ${className}`}><Text>{msg}</Text></View>
    </View>
  }

  async onCreateDeviceGroup() {
    const {
      groupName,
    } = this.state
    try {
      if (groupName.length === 0) throw new Error('分组名称不能为空')
      await DeviceGroup.CreateDeviceGroup(groupName, '')
      await this.getDeviceGroup()
      this.setState({
        addGroupLoading: false,
        addGroupInputShow: false,
        groupName: '',
      })
    } catch (error) {
      Taro.showModal({
        title: '添加失败',
        content: error.message,
        showCancel: false
      })
    }
    this.setState({
      addGroupLoading: false
    })
  }

  async onRemoveDeviceGroup(x: DeviceGroup, checklist: boolean = true) {
    try {
      const { deviceGroupList } = this.state
      Taro.showLoading({
        title: '删除中',
      })
      if (checklist) {
        Taro.hideLoading()
        const a = await DeviceList.GetDeviceList(x.get_id());
        if (a.length > 0) {
          const res = await Taro.showModal({
            title: '提示',
            content: `当前分组中存在${a.length}个设备，是否确定删除分组？分组删除后，设备自动移动到默认分组。`,
          })
          if (res.confirm) {
            this.onRemoveDeviceGroup(x, false)
          }
          return
        }
      }
      for (let index = 0; index < deviceGroupList.length; index++) {
        const element = deviceGroupList[index];
        if (element.allowDelete === false) {
          // 传递一个id，用于删除前转移设备列表到其分组
          await x.Remove(element.get_id())
          await this.getDeviceGroup()
          break;
        }
      }
    } catch (error) {
      Taro.showModal({
        title: '删除失败',
        content: error.message,
        showCancel: false
      })
    }
    Taro.hideLoading()
  }

  homeAtDrawer() {
    const {
      homeAtDrawerShow,
      deviceGroupList,
      selectDeviceGroupIndex,
      addGroupInputShow,
      addGroupLoading,
      groupName,
    } = this.state
    // 分组列表
    const arr = deviceGroupList.map((x, i) => {
      return <View
        key={i}
        className={`at-row deviceGroupListItem ${selectDeviceGroupIndex === i ? 'select' : ''}`}
        onClick={() => {
          this.setState({
            homeAtDrawerShow: false,
            selectDeviceGroupIndex: i,
            deviceList: []
          }, () => {
            Taro.vibrateShort()
            this.getDeviceList()
          })
        }}
        onLongPress={() => {
          if (deviceGroupList.length > 1 && x.allowDelete) {
            Taro.showModal({
              title: '提示',
              content: `是否需要删除分组？【${x.name}】`,
              success: async (res) => {
                if (res.confirm) {
                  this.onRemoveDeviceGroup(x)
                }
              }
            })
          }
        }}
      >
        <View className='at-col at-col-3 right'>
          {selectDeviceGroupIndex === i && <View className='at-icon at-icon-chevron-right animated fadeInLeft infinite'></View>}
        </View>
        <View className='at-col at-col-6'>{x.name}</View>
        <View className='at-col at-col-3 left'>
          {selectDeviceGroupIndex === i && <View className='at-icon at-icon-chevron-left animated fadeInRight infinite'></View>}
        </View>
      </View>
    })

    return <AtDrawer
      show={homeAtDrawerShow}
      right={false}
      mask
      onClose={() => {
        this.setState({
          homeAtDrawerShow: false
        })
      }}

    >
      {/* 顶部LOGO */}
      <View className='drawer-item-top center-horizontally' onClick={() => {
        this.setState({
          homeAtDrawerShow: false,
        }, () => {
          // 让动画走完后跳转
          setTimeout(() => {
            this.setState({
              pageCurrent: PAGES.ALERT,
            })
          }, 420);
        })
      }}>
        <Image className='image-logo' src={IMAGES.logo} />
      </View>
      {/* 渲染列表 */}
      {arr}
      {addGroupInputShow === true && <View className='at-row add-group-input animated bounceInLeft'>
        <View className='at-col at-col-8 at-col__offset-1 center-horizontally'>
          <Input
            className='input'
            disabled={addGroupLoading}
            placeholder="请输入分组名称"
            value={groupName}
            maxlength={20}
            onInput={(e) => this.handleClick('groupName', e.detail.value)} />
        </View>
        <View className='at-col at-col-3 center-horizontally'>
          <View className='cancel' onClick={() => {
            if (!addGroupLoading) {
              this.setState({
                addGroupInputShow: false,
                groupName: '',
                addGroupLoading: false
              })
            }
          }}>取消</View>
        </View>
      </View>}
      {/* 添加分组按钮 */}
      <View className='add-group-btn'>
        <AtButton loading={addGroupLoading} disabled={addGroupLoading} type={addGroupInputShow ? 'primary' : 'secondary'} onClick={() => {
          if (addGroupInputShow) {
            // 添加的逻辑
            this.setState({
              addGroupLoading: true
            }, async () => {
              this.onCreateDeviceGroup()
            })
          } else {
            this.setState({
              addGroupInputShow: true,
              groupName: '',
              addGroupLoading: false
            })
          }
        }}>{addGroupInputShow ? '确定添加' : '添加分组'}</AtButton>
      </View>
      <View className='tips'>长按分组名称可以删除分组</View>
    </AtDrawer>
  }

  deviceList() {
    const { deviceList, status, deviceMode } = this.state
    return deviceList.map((x, i) => {
      return <View className='at-row led-list' hidden={status !== STATUS.LOADING} >
        <View key={i} className='at-col at-col-12 list-periphery'>
          <View className='border'>
            <View className='at-row device-list'>
              <View className='at-col at-col-4 funcl' hoverClass='hover' hoverStartTime={20} hoverStayTime={70} onClick={() => {
                // 功能选择
                this.setState({
                  deviceInfoAtFloatLayoutIsOpened: true,
                  selectDeviceIndex: i,
                  inputName: x.name
                })
              }}>
                {/* 设备图片 */}
                <View className='at-row' style={{ height: "70%" }}>
                  <View className='at-col at-col-12 center-horizontally'>
                    <Image className='deviceMode-iconPath' src={x.searchDeviceMode(deviceMode).iconPath} />
                  </View>
                </View>
                {/* 状态标识 */}
                <View className='at-row' style={{ height: "30%" }}>
                  <View className='at-col at-col-12 center-horizontally'>
                    {x.describeDeviceInfo && <View>
                      {x.describeDeviceInfo.Online === 1 && <View className='Online'>设备在线</View>}
                      {x.describeDeviceInfo.Online === 0 && <View className='Offline'>设备离线</View>}
                    </View>}
                  </View>
                </View>

              </View>
              {x.modeId === 'b5416b755f546ad9013bbe2d299834dd' && <View className='at-col at-col-8'>
                {/* 轮播信息 */}
                <View className='at-row carousel-text-row'>
                  <View className='at-col at-col-12'>
                    <View className='carousel-text '>
                      <View className='text'>{x.carouselText}</View>
                    </View>
                  </View>
                </View>
                {/* 信息显示 */}
                <View className='at-row infos-row center-horizontally justify-content-flex-start'>
                  <View className='at-col at-col-6'>设备名称：{x.name}</View>
                </View>
                {/* 功能按钮 */}
                <View className='at-row btns-row'>
                  {/* 轮播文本 */}
                  <View className='at-col at-col-3 center-horizontally'>
                    <View className='func' hoverClass='hover' hoverStartTime={20} hoverStayTime={70} onClick={() => {
                      Taro.navigateTo({
                        url: x.searchDeviceMode(deviceMode).getHandlePath(x, DeviceModeHandlePath.LedTextHandle),
                      })
                    }}>
                      <View className='center-horizontally'>
                        <Image className='device-mode-func-icon' src={IMAGES.gengxinbiangeng} />
                      </View>
                      <View className='title'>轮播文本</View>
                    </View>
                  </View>
                  {/* 播放语音 */}
                  <View className='at-col at-col-3 center-horizontally'>
                    <View className='disabled'  >
                      <View className='center-horizontally'>
                        <Image className='device-mode-func-icon' src={IMAGES.tongzhigonggao} />
                      </View>
                      <View className='title'>播放语音</View>
                    </View>
                  </View>
                  {/* 自动更换 */}
                  <View className='at-col at-col-3 center-horizontally'>
                    <View className='func' hoverClass='hover' hoverStartTime={20} hoverStayTime={70} onClick={() => {
                      Taro.navigateTo({
                        url: x.searchDeviceMode(deviceMode).getHandlePath(x, DeviceModeHandlePath.AutoChanageLedText),
                      })
                    }} >
                      <View className='center-horizontally'>
                        <Image className='device-mode-func-icon' src={IMAGES.jiagouliucheng} />
                      </View>
                      <View className='title'>自动更换</View>
                    </View>
                  </View>
                  {/* 历史操作 */}
                  <View className='at-col at-col-3 center-horizontally'>
                    <View className='disabled' hoverClass='hover' hoverStartTime={20} hoverStayTime={70} >
                      <View className='center-horizontally'>
                        <Image className='device-mode-func-icon' src={IMAGES.rilirichengjihua} />
                      </View>
                      <View className='title'>历史操作</View>
                    </View>
                  </View>
                </View>
              </View>}
              {x.modeId === '8e5be7055f8d82a601fce9e84e2bfa5d' && <View className='at-col at-col-8 center-horizontally'>
                <View>
                  <Switch  />
                </View>
              </View>}
            </View>
          </View>
        </View>
      </View>

    })
  }

  async onRemoveDevice() {
    const { selectDeviceIndex, deviceList } = this.state
    let del = false;
    try {
      const dev = deviceList[selectDeviceIndex]
      const res = await Taro.showModal({
        title: '提示',
        content: '是否删除设备？',
      })
      if (res.confirm) {
        del = true;
        Taro.showLoading({
          title: '删除中',
        })
        this.setState({
          deviceInfoAtFloatLayoutIsOpened: false
        })
        const a = await dev.remove()
        console.log(a);

        await this.getDeviceList()
      }
    } catch (error) {
      Taro.showModal({
        title: '操作失败',
        content: error.message,
        showCancel: false
      })
    }
    if (del) Taro.hideLoading()
  }

  async onSaveName() {
    const { selectDeviceIndex, deviceList, inputName } = this.state

    try {
      const dev = deviceList[selectDeviceIndex]
      Taro.showLoading({
        title: '保存中',
      })
      this.setState({
        deviceInfoAtFloatLayoutIsOpened: false
      })
      await dev.saveName(inputName)
      this.setState({ deviceList })
    } catch (error) {
      Taro.showModal({
        title: '操作失败',
        content: error.message,
        showCancel: false
      })
    }
    Taro.hideLoading()
  }



  deviceInfoAtFloatLayout() {
    const { deviceInfoAtFloatLayoutIsOpened, selectDeviceIndex, deviceList, inputName } = this.state
    const dev = deviceList[selectDeviceIndex]
    return <AtFloatLayout
      isOpened={deviceInfoAtFloatLayoutIsOpened}
      title="设备信息"
      onClose={() => { this.setState({ deviceInfoAtFloatLayoutIsOpened: false }) }}
    >
      <View className='device-info'>
        <View className='at-row device-info-row'>
          <View className='at-col at-col-3 at-col__offset-1'>设备名称</View>
          <View className='at-col at-col-7'> <Input className='input' type='text' value={inputName} onInput={(e) => this.handleClick('inputName', e.detail.value)} /></View>
        </View>

        <View className='at-row device-info-row'>
          <View className='at-col at-col-3 at-col__offset-1'>设备型号</View>
          <View className='at-col at-col-7'><View>{dev?.info?.deviceModel}</View></View>
        </View>

        <View className='at-row device-info-row'>
          <View className='at-col at-col-3 at-col__offset-1'>固件版本</View>
          <View className='at-col at-col-7'><View>{dev?.info?.mainFirmVer}</View></View>
        </View>

        <View className='at-row device-info-row device-info-row-btn'>
          <View className='at-col at-col-10 at-col__offset-1'>
            <AtButton type='secondary' onClick={this.onSaveName.bind(this)}>保存修改</AtButton>
          </View>
        </View>

        <View className='at-row device-info-row'>
          <View
            className='at-col at-col-10 at-col__offset-1 center-horizontally delete'
            hoverClass='hover'
            hoverStartTime={20}
            hoverStayTime={70}
            onClick={this.onRemoveDevice.bind(this)}
          >
            <View>我要删除设备</View>
          </View>
        </View>

      </View>
    </AtFloatLayout>
  }

  render() {
    const { status, pageCurrent, deviceGroupList, selectDeviceGroupIndex, deviceList } = this.state
    return (
      <View className='index'>
        {this.deviceInfoAtFloatLayout()}
        {/* 主页 */}
        {pageCurrent === PAGES.HOME &&
          <View className="page-periphery">
            {this.homeAtDrawer()}
            <ScrollView scrollY className='scroll'>
              <View className='at-row top'></View>
              <View className='at-row'>
                {/* 头像 */}
                <View className='at-col at-col-4'>
                  <View className='user-avatar-url animated rotateInDownLeft dowebok'>
                    <OpenData type="userAvatarUrl" />
                  </View>
                </View>
                {/* 昵称 */}
                <View className='at-col at-col-8'>
                  <View className='user-nick-name'>
                    <Text>您好，</Text>
                    <OpenData type="userNickName" />
                  </View>
                  {/* 选择分组 */}
                  <View className='group' hoverClass='hover' hoverStartTime={20} hoverStayTime={70} onClick={() => {
                    // 打开抽屉
                    this.setState({
                      homeAtDrawerShow: true
                    })
                  }} >
                    <View className='at-row'>
                      <View className='at-col at-col-9 text'>{deviceGroupList[selectDeviceGroupIndex]?.name}</View>
                      <View className='at-col at-col-3 center-horizontally'>
                        <View className='at-icon at-icon-chevron-down'></View>
                      </View>
                    </View>
                  </View>
                </View>
              </View>
              {/* 设备主体 */}
              <View>
                {deviceList.length === 0 && <View className='at-row led-list' hidden={status !== STATUS.LOADING} >
                  {/* 添加 */}
                  {this.addView()}
                </View>}
                {/* 列表 */}
                {this.deviceList()}
                {deviceList.length > 0 && <View className='at-row'>
                  <View
                    className='at-col at-col-12 center-horizontally add-dev-text'
                    hoverClass='hover' hoverStartTime={20} hoverStayTime={70} onClick={() => {
                      const { GetDeviceListNow } = this.state
                      if (!GetDeviceListNow) {
                        this.onBindDeviceSelect()
                      }
                    }}
                  >添加新设备</View>
                </View>}
              </View>
            </ScrollView>
            {/* 加载动画 */}
            {/* <AtActivityIndicator content='加载中...'></AtActivityIndicator> */}
          </View>}
        {/* 关于 */}
        {pageCurrent === PAGES.ALERT &&
          <View className="page-periphery alert">
            <View className='top center-horizontally'>
              <Image className='image-logo animated rotateInDownLeft dowebok' src={IMAGES.logo} />
            </View>
            <View className='bottom'>
              {this.alertInfo('说明：', T.T0001, 'long')}
              {this.alertInfo('开源地址：', 'https://gitee.com/junlan2013/esp32_led_serverless.git', 'long')}
              {this.alertInfo('版本号：', appVersion)}
              {this.alertInfo('小程序云开发：', miniprogramDeveloper)}
              {this.alertInfo('MCU软件：', hardwareDeveloper)}
              {this.alertInfo('电路设计：', '同上')}
            </View>
          </View>}

        {/* 底部导航 */}
        <View className='page-tabbar'>
          <AtTabBar
            tabList={[
              { title: '主页', iconType: 'home', text: 'new' },
              { title: '关于', iconType: 'alert-circle' },
            ]}
            onClick={this.handleClick.bind(this, 'pageCurrent')}
            current={pageCurrent}
          />
        </View>
      </View>
    )
  }
}
